/*
    This is a single-header-file library that provides a small, portable, and
    easy-to-use graphical user interface toolkit written in ANSI C. It was designed as
    a simple embeddable user interface for application and does not have any
    dependencies, a default render backend or OS window and input handling
    but instead provides a very modular library with a carefully designed API
    that allows you to use it in a wide variety of environments and sceneries.

    This library is in the public domain and can be used used for any purpose
    without any restrictions.
*/

#ifndef NK_H_
#define NK_H_

#ifdef __cplusplus
extern "C" {
#endif

/*
 * ==============================================================
 * 
 *                          CONFIG
 * 
 * ===============================================================
 */
#ifndef NK_PRIVATE
    #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
        #include <stdint.h>
        #define NK_UINT32 uint32_t
        #define NK_INT32  int32_t
        #define NK_UINT16 uint16_t
        #define NK_INT16  int16_t
        #define NK_UINT8  uint8_t
        #define NK_INT8   int8_t
        #define NK_SIZE   uintptr_t
        #define NK_BOOL   NK_INT32
    #else
        #define NK_UINT32 unsigned int
        #define NK_INT32  int
        #define NK_UINT16 unsigned short
        #define NK_INT16  short
        #define NK_UINT8  unsigned char
        #define NK_INT8   char
        #define NK_SIZE   unsigned long
        #define NK_BOOL   int
    #endif
#endif

#if defined(NK_INCLUDE_FIXED_TYPES)
    #include <stdint.h>
    #define NK_UINT32 uint32_t
    #define NK_INT32  int32_t
    #define NK_UINT16 uint16_t
    #define NK_INT16  int16_t
    #define NK_UINT8  uint8_t
    #define NK_INT8   int8_t
    #define NK_SIZE   uintptr_t
    #define NK_BOOL   int
#endif

#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
    #include <stdlib.h> /* malloc, free */
    #define NK_MALLOC(sz) malloc(sz)
    #define NK_FREE(ptr) free(ptr)
#endif

#ifdef NK_INCLUDE_STANDARD_IO
    #include <stdio.h> /* fopen, fclose, fread, fwrite, fseek, ftell */
#endif

#ifdef NK_INCLUDE_STANDARD_VARARGS
    #include <stdarg.h> /* va_list, va_start, va_end */
#endif

#ifdef NK_ASSERT
    #include <assert.h>
    #define NK_ASSERT(expr) assert(expr)
#endif

#ifndef NK_API
    #ifdef NK_PRIVATE
        #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
            #define NK_API static inline
        #else
            #define NK_API static
        #endif
    #else
        #define NK_API extern
    #endif
#endif

#define NK_FLAG(x) (1 << (x))

/*
 * ===============================================================
 * 
 *                          BASIC
 * 
 * ===============================================================
 */
struct nk_color {NK_UINT8 r,g,b,a;};
struct nk_vec2 {float x,y;};
struct nk_vec2i {short x, y;};
struct nk_rect {float x,y,w,h;};
struct nk_recti {short x,y,w,h;};
typedef char nk_glyph[4];
typedef union {void *ptr; int id;} nk_handle;
struct nk_image {nk_handle handle; unsigned short w, h; unsigned short region[4];};
struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;};
struct nk_scroll {unsigned short x, y;};

enum nk_heading {NK_UP, NK_RIGHT, NK_DOWN, NK_LEFT};
enum nk_button_behavior {NK_BUTTON_DEFAULT = 0, NK_BUTTON_REPEATER};
enum nk_modify {NK_FIXED = 0, NK_MODIFIABLE = 1};
enum nk_orientation {NK_VERTICAL, NK_HORIZONTAL};
enum nk_collapse_states {NK_MINIMIZED = 0, NK_MAXIMIZED = 1};
enum nk_show_states {NK_HIDDEN = 0, NK_SHOWN = 1};
enum nk_chart_type {NK_CHART_LINES, NK_CHART_COLUMN, NK_CHART_MAX};
enum nk_chart_event {NK_CHART_HOVERING = 0x01, NK_CHART_CLICKED = 0x02};
enum nk_color_format {NK_RGB, NK_RGBA};
enum nk_popup_type {NK_POPUP_STATIC, NK_POPUP_DYNAMIC};
enum nk_layout_format {NK_DYNAMIC, NK_STATIC};
enum nk_tree_type {NK_TREE_NODE, NK_TREE_TAB};

typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size size);
typedef void(*nk_plugin_free)(nk_handle, void *old);
typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_glyph glyph);
typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*);
typedef void(*nk_plugin_copy)(nk_handle, const char*, int len);

struct nk_allocator {
    nk_handle userdata;
    nk_plugin_alloc alloc;
    nk_plugin_free free;
};

struct nk_style_item {
    enum {NK_STYLE_ITEM_COLOR, NK_STYLE_ITEM_IMAGE} type;
    union {struct nk_color color; struct nk_image image;} data;
};

struct nk_user_font {
    nk_handle userdata;
    float height;
    float(*width)(nk_handle, float h, const char*, int len);
    void(*query)(nk_handle, float font_height, struct nk_user_font_glyph*, nk_glyph glyph, int len);
};

/*
 * ===============================================================
 * 
 *                          BUFFER
 * 
 * ===============================================================
 */
struct nk_buffer_marker {
    int active;
    nk_size offset;
};

struct nk_buffer {
    struct nk_buffer_marker marker[2];
    struct nk_allocator pool;
    enum {NK_BUFFER_FIXED, NK_BUFFER_DYNAMIC} type;
    nk_size capacity;
    nk_size size;
    void *memory;
};

/*
 * ===============================================================
 * 
 *                          STRING
 * 
 * ===============================================================
 */
struct nk_str {
    struct nk_buffer buffer;
    int len;
};

/*
 * ===============================================================
 * 
 *                          TEXT EDITOR
 * 
 * ===============================================================
 */
struct nk_text_edit {
    struct nk_str string;
    nk_plugin_filter filter;
    struct nk_scroll scrollbar;
    int cursor;
    int select_start;
    int select_end;
    unsigned char mode;
    unsigned char single_line;
    unsigned char active;
    unsigned char padding1;
    float cursor_x, cursor_y;
    int has_preferred_x;
    unsigned char select_all_word_mode;
    unsigned char padding2;
    void *userdata;
    nk_plugin_paste paste;
    nk_plugin_copy copy;
};

/*
 * ===============================================================
 * 
 *                          DRAWING
 * 
 * ===============================================================
 */
enum nk_command_type {
    NK_COMMAND_NOP,
    NK_COMMAND_SCISSOR,
    NK_COMMAND_LINE,
    NK_COMMAND_CURVE,
    NK_COMMAND_RECT,
    NK_COMMAND_RECT_FILLED,
    NK_COMMAND_RECT_MULTI_COLOR,
    NK_COMMAND_TRIANGLE,
    NK_COMMAND_TRIANGLE_FILLED,
    NK_COMMAND_CIRCLE,
    NK_COMMAND_CIRCLE_FILLED,
    NK_COMMAND_ARC,
    NK_COMMAND_ARC_FILLED,
    NK_COMMAND_IMAGE,
    NK_COMMAND_TEXT,
    NK_COMMAND_CUSTOM
};

struct nk_command {
    enum nk_command_type type;
    nk_size next;
};

struct nk_command_scissor {
    struct nk_command header;
    struct nk_recti clip;
};

struct nk_command_line {
    struct nk_command header;
    unsigned short line_thickness;
    struct nk_vec2i begin;
    struct nk_vec2i end;
    struct nk_color color;
};

struct nk_command_curve {
    struct nk_command header;
    unsigned short line_thickness;
    struct nk_vec2i begin;
    struct nk_vec2i end;
    struct nk_vec2i ctrl[2];
    struct nk_color color;
};

struct nk_command_rect {
    struct nk_command header;
    unsigned short rounding;
    unsigned short line_thickness;
    struct nk_recti r;
    struct nk_color color;
};

struct nk_command_rect_filled {
    struct nk_command header;
    unsigned short rounding;
    struct nk_recti r;
    struct nk_color color;
};

struct nk_command_rect_multi_color {
    struct nk_command header;
    struct nk_recti r;
    struct nk_color left;
    struct nk_color top;
    struct nk_color bottom;
    struct nk_color right;
};

struct nk_command_triangle {
    struct nk_command header;
    unsigned short line_thickness;
    struct nk_vec2i a;
    struct nk_vec2i b;
    struct nk_vec2i c;
    struct nk_color color;
};

struct nk_command_triangle_filled {
    struct nk_command header;
    struct nk_vec2i a;
    struct nk_vec2i b;
    struct nk_vec2i c;
    struct nk_color color;
};

struct nk_command_circle {
    struct nk_command header;
    struct nk_recti r;
    unsigned short line_thickness;
    struct nk_color color;
};

struct nk_command_circle_filled {
    struct nk_command header;
    struct nk_recti r;
    struct nk_color color;
};

struct nk_command_arc {
    struct nk_command header;
    struct nk_recti r;
    float a[2];
    unsigned short line_thickness;
    struct nk_color color;
};

struct nk_command_arc_filled {
    struct nk_command header;
    struct nk_recti r;
    float a[2];
    struct nk_color color;
};

struct nk_command_image {
    struct nk_command header;
    struct nk_recti r;
    struct nk_image img;
    struct nk_color col;
};

struct nk_command_text {
    struct nk_command header;
    const struct nk_user_font *font;
    struct nk_recti background;
    struct nk_color foreground;
    int length;
    char string[1];
};

struct nk_command_custom {
    struct nk_command header;
    void *userdata;
    void (*callback)(void *canvas, struct nk_recti clip);
};

/*
 * ===============================================================
 * 
 *                          INPUT
 * 
 * ===============================================================
 */
enum nk_keys {
    NK_KEY_SHIFT,
    NK_KEY_CTRL,
    NK_KEY_DEL,
    NK_KEY_ENTER,
    NK_KEY_TAB,
    NK_KEY_BACKSPACE,
    NK_KEY_COPY,
    NK_KEY_CUT,
    NK_KEY_PASTE,
    NK_KEY_UP,
    NK_KEY_DOWN,
    NK_KEY_LEFT,
    NK_KEY_RIGHT,
    NK_KEY_TEXT_INSERT_MODE,
    NK_KEY_TEXT_REPLACE_MODE,
    NK_KEY_TEXT_RESET_MODE,
    NK_KEY_TEXT_LINE_START,
    NK_KEY_TEXT_LINE_END,
    NK_KEY_TEXT_WORD_LEFT,
    NK_KEY_TEXT_WORD_RIGHT,
    NK_KEY_TEXT_UNDO,
    NK_KEY_TEXT_REDO,
    NK_KEY_SCROLL_START,
    NK_KEY_SCROLL_END,
    NK_KEY_SCROLL_DOWN,
    NK_KEY_SCROLL_UP,
    NK_KEY_MAX
};

enum nk_buttons {
    NK_BUTTON_LEFT,
    NK_BUTTON_MIDDLE,
    NK_BUTTON_RIGHT,
    NK_BUTTON_DOUBLE,
    NK_BUTTON_MAX
};

struct nk_mouse_button {
    int down;
    unsigned int clicked;
    struct nk_vec2 clicked_pos;
};

struct nk_mouse {
    struct nk_mouse_button buttons[NK_BUTTON_MAX];
    struct nk_vec2 pos;
    struct nk_vec2 prev;
    struct nk_vec2 delta;
    struct nk_vec2 scroll_delta;
    unsigned char grab;
    unsigned char grabbed;
    unsigned char ungrab;
};

struct nk_key {
    int down;
    unsigned int clicked;
};

struct nk_keyboard {
    struct nk_key keys[NK_KEY_MAX];
    char text[16];
    int text_len;
};

struct nk_input {
    struct nk_keyboard keyboard;
    struct nk_mouse mouse;
};

/*
 * ===============================================================
 * 
 *                          STYLE
 * 
 * ===============================================================
 */
struct nk_style_text {
    struct nk_color color;
    struct nk_vec2 padding;
};

struct nk_style_button {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* text */
    struct nk_color text_background;
    struct nk_color text_normal;
    struct nk_color text_hover;
    struct nk_color text_active;

    /* properties */
    float border;
    float rounding;
    struct nk_vec2 padding;
    struct nk_vec2 image_padding;
    struct nk_vec2 touch_padding;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_toggle {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* cursor */
    struct nk_style_item cursor_normal;
    struct nk_style_item cursor_hover;

    /* text */
    struct nk_color text_normal;
    struct nk_color text_hover;
    struct nk_color text_active;
    struct nk_color text_background;

    /* properties */
    float border;
    float rounding;
    struct nk_vec2 padding;
    struct nk_vec2 touch_padding;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_selectable {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item pressed;

    /* background (inactive) */
    struct nk_style_item normal_active;
    struct nk_style_item hover_active;
    struct nk_style_item pressed_active;

    /* text */
    struct nk_color text_normal;
    struct nk_color text_hover;
    struct nk_color text_pressed;

    /* text (inactive) */
    struct nk_color text_normal_active;
    struct nk_color text_hover_active;
    struct nk_color text_pressed_active;
    struct nk_color text_background;

    /* properties */
    float rounding;
    struct nk_vec2 padding;
    struct nk_vec2 touch_padding;
    struct nk_vec2 image_padding;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_slider {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* background bar */
    struct nk_color bar_normal;
    struct nk_color bar_hover;
    struct nk_color bar_active;
    struct nk_color bar_filled;

    /* cursor */
    struct nk_style_item cursor_normal;
    struct nk_style_item cursor_hover;
    struct nk_style_item cursor_active;

    /* properties */
    float border;
    float rounding;
    float bar_height;
    struct nk_vec2 padding;
    struct nk_vec2 spacing;
    struct nk_vec2 cursor_size;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_progress {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* cursor */
    struct nk_style_item cursor_normal;
    struct nk_style_item cursor_hover;
    struct nk_style_item cursor_active;
    struct nk_color cursor_border_color;

    /* properties */
    float rounding;
    float border;
    float cursor_border;
    struct nk_vec2 padding;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_scrollbar {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* cursor */
    struct nk_style_item cursor_normal;
    struct nk_style_item cursor_hover;
    struct nk_style_item cursor_active;
    struct nk_color cursor_border_color;

    /* properties */
    float border;
    float rounding;
    float border_cursor;
    float rounding_cursor;
    struct nk_vec2 padding;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_edit {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;
    struct nk_style_scrollbar scrollbar;

    /* cursor  */
    struct nk_color cursor_normal;
    struct nk_color cursor_hover;
    struct nk_color cursor_text_normal;
    struct nk_color cursor_text_hover;

    /* text */
    struct nk_color text_normal;
    struct nk_color text_hover;
    struct nk_color text_active;

    /* selection */
    struct nk_color selected_normal;
    struct nk_color selected_hover;
    struct nk_color selected_text_normal;
    struct nk_color selected_text_hover;

    /* properties */
    float border;
    float rounding;
    float cursor_size;
    struct nk_vec2 scrollbar_size;
    struct nk_vec2 padding;
    float row_padding;
};

struct nk_style_property {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* text */
    struct nk_color label_normal;
    struct nk_color label_hover;
    struct nk_color label_active;

    /* symbols */
    struct nk_style_button left_button;
    struct nk_style_button right_button;

    /* properties */
    float border;
    float rounding;
    struct nk_vec2 padding;

    struct nk_style_edit edit;
    struct nk_style_button inc_button;
    struct nk_style_button dec_button;

    /* optional user callbacks */
    void *userdata;
    void (*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
    void (*draw_end)(struct nk_command_buffer*, nk_handle userdata);
};

struct nk_style_chart {
    /* background */
    struct nk_style_item background;
    struct nk_color border_color;
    struct nk_color selected_color;
    struct nk_color color;

    /* properties */
    float border;
    float rounding;
    struct nk_vec2 padding;
};

struct nk_style_combo {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;
    struct nk_color border_color;

    /* label */
    struct nk_color label_normal;
    struct nk_color label_hover;
    struct nk_color label_active;

    /* symbol */
    struct nk_color symbol_normal;
    struct nk_color symbol_hover;
    struct nk_color symbol_active;

    /* button */
    struct nk_style_button button;

    /* properties */
    float border;
    float rounding;
    struct nk_vec2 content_padding;
    struct nk_vec2 button_padding;
    struct nk_vec2 spacing;
};

struct nk_style_tab {
    /* background */
    struct nk_style_item background;
    struct nk_color border_color;
    struct nk_color text;

    /* button */
    struct nk_style_button tab_maximize_button;
    struct nk_style_button tab_minimize_button;
    struct nk_style_button node_maximize_button;
    struct nk_style_button node_minimize_button;

    /* properties */
    float border;
    float rounding;
    float indent;
    struct nk_vec2 padding;
    struct nk_vec2 spacing;
};

struct nk_style_window_header {
    /* background */
    struct nk_style_item normal;
    struct nk_style_item hover;
    struct nk_style_item active;

    /* button */
    struct nk_style_button close_button;
    struct nk_style_button minimize_button;
    struct nk_color close_symbol;
    struct nk_color minimize_symbol;
    struct nk_color maximize_symbol;

    /* title */
    struct nk_color title_normal;
    struct nk_color title_hover;
    struct nk_color title_active;

    /* properties */
    float rounding;
    struct nk_vec2 padding;
    struct nk_vec2 label_padding;
    struct nk_vec2 spacing;
};

struct nk_style_window {
    struct nk_style_window_header header;
    struct nk_style_item fixed_background;
    struct nk_color background;

    struct nk_color border_color;
    struct nk_color popup_border_color;
    struct nk_color combo_border_color;
    struct nk_color contextual_border_color;
    struct nk_color menu_border_color;
    struct nk_color group_border_color;
    struct nk_color tooltip_border_color;
    struct nk_style_item scaler;

    float border;
    float combo_border;
    float contextual_border;
    float menu_border;
    float group_border;
    float tooltip_border;
    float popup_border;
    float min_row_height_padding;

    float rounding;
    struct nk_vec2 spacing;
    struct nk_vec2 scrollbar_size;
    struct nk_vec2 min_size;
    struct nk_vec2 padding;
    struct nk_vec2 group_padding;
    struct nk_vec2 popup_padding;
    struct nk_vec2 combo_padding;
    struct nk_vec2 contextual_padding;
    struct nk_vec2 menu_padding;
    struct nk_vec2 tooltip_padding;
};

struct nk_style {
    const struct nk_user_font *font;
    struct nk_cursor *cursors[7];
    struct nk_cursor *cursor_active;
    struct nk_style_item *cursor_last;
    int cursor_visible;

    struct nk_style_text text;
    struct nk_style_button button;
    struct nk_style_button contextual_button;
    struct nk_style_button menu_button;
    struct nk_style_toggle option;
    struct nk_style_toggle checkbox;
    struct nk_style_selectable selectable;
    struct nk_style_slider slider;
    struct nk_style_progress progress;
    struct nk_style_property property;
    struct nk_style_edit edit;
    struct nk_style_chart chart;
    struct nk_style_scrollbar scrollh;
    struct nk_style_scrollbar scrollv;
    struct nk_style_tab tab;
    struct nk_style_combo combo;
    struct nk_style_window window;
};

/*
 * ===============================================================
 * 
 *                          CONTEXT
 * 
 * ===============================================================
 */
struct nk_memory_status {
    void *memory;
    unsigned int type;
    nk_size size;
    nk_size allocated;
    nk_size needed;
    nk_size calls;
};

struct nk_command_buffer {
    void *base;
    struct nk_rect clip;
    int use_clipping;
    nk_size begin, end, last;
    nk_size capacity;
    nk_size needed;
};

struct nk_panel {
    enum nk_panel_type {
        NK_PANEL_WINDOW     = NK_FLAG(0),
        NK_PANEL_GROUP      = NK_FLAG(1),
        NK_PANEL_POPUP      = NK_FLAG(2),
        NK_PANEL_CONTEXTUAL= NK_FLAG(3),
        NK_PANEL_COMBO      = NK_FLAG(4),
        NK_PANEL_MENU       = NK_FLAG(5),
        NK_PANEL_TOOLTIP    = NK_FLAG(6)
    } type;
    NK_UINT32 flags;
    struct nk_rect bounds;
    unsigned short offset_x, offset_y;
    float at_x, at_y, max_x;
    float footer_height;
    float header_height;
    float border;
    unsigned int has_scrolling;
    struct nk_rect clip;
    struct nk_menu_state {
        int x, y, w, h;
        struct nk_scroll offset;
    } menu;
    struct nk_row_layout {
        enum nk_layout_format format;
        int index, height, columns;
        const float *ratio;
        float item_width, item_offset;
        float filled, item_cropping;
        struct nk_rect item;
        int tree_depth;
        float templates[16];
    } row;
    struct nk_chart {
        int slot;
        float x, y, w, h;
        enum nk_chart_type type;
        struct nk_color color;
        struct nk_color highlight;
        int count;
        float last[4];
    } chart;
    struct nk_command_buffer *buffer;
    struct nk_panel *parent;
};

struct nk_window {
    unsigned int seq;
    unsigned int stamp;
    NK_UINT32 flags;
    struct nk_rect bounds;
    struct nk_scroll scrollbar;
    struct nk_command_buffer buffer;
    struct nk_panel *layout;
    float scrollbar_hiding_timer;
    /* persistent widget state */
    struct nk_property_state {
        int active, prev;
        char name[64];
        int editing;
        int seq;
    } property;
    struct nk_popup_state {
        int active;
        unsigned type;
        struct nk_rect bounds;
        unsigned int name;
        int combo_count;
        int con_count;
        int con_begin;
        int active_con;
    } popup;
    struct nk_edit_state {
        unsigned int name;
        unsigned int seq;
        unsigned int old;
        int active, prev;
        int cursor;
        int sel_start, sel_end;
        struct nk_scroll scrollbar;
        unsigned char mode;
        unsigned char single_line;
    } edit;
    unsigned int scrolled;
    int tables_count;
    struct nk_table* tables;
    int table_size;
};

struct nk_context {
    /* public */
    struct nk_input input;
    struct nk_style style;
    struct nk_buffer memory;
    struct nk_command_buffer *painter;
    void *userdata;

    /* private */
    struct nk_buffer temp_memory;
    struct nk_window *begin, *end, *active;
    struct nk_panel *current;
    int count;
    unsigned int seq, build;
    NK_UINT32 flags;
    int active_z_layer;
};

/*
 * ===============================================================
 * 
 *                          CONTEXT
 * 
 * ===============================================================
 */
NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*);
NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*);
NK_API void nk_clear(struct nk_context*);
NK_API void nk_free(struct nk_context*);
NK_API void nk_set_user_data(struct nk_context*, nk_handle handle);
NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, NK_UINT32 flags);
NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, NK_UINT32 flags);
NK_API void nk_end(struct nk_context *ctx);
NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
NK_API struct nk_vec2 nk_window_get_size(const struct nk_context *ctx);
NK_API float nk_window_get_width(const struct nk_context *ctx);
NK_API float nk_window_get_height(const struct nk_context *ctx);
NK_API struct nk_panel* nk_window_get_panel(struct nk_context *ctx);
NK_API struct nk_rect nk_window_get_content_region(struct nk_context *ctx);
NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context *ctx);
NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context *ctx);
NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context *ctx);
NK_API struct nk_command_buffer* nk_window_get_canvas(struct nk_context *ctx);
NK_API int nk_window_has_focus(const struct nk_context *ctx);
NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
NK_API int nk_window_is_closed(struct nk_context *ctx, const char *name);
NK_API int nk_window_is_hidden(struct nk_context *ctx, const char *name);
NK_API int nk_window_is_active(struct nk_context *ctx, const char *name);
NK_API int nk_window_is_hovered(struct nk_context *ctx);
NK_API int nk_window_is_any_hovered(struct nk_context *ctx);
NK_API int nk_item_is_any_active(struct nk_context *ctx);
NK_API void nk_window_set_bounds(struct nk_context *ctx, struct nk_rect bounds);
NK_API void nk_window_set_position(struct nk_context *ctx, struct nk_vec2 pos);
NK_API void nk_window_set_size(struct nk_context *ctx, struct nk_vec2 size);
NK_API void nk_window_set_focus(struct nk_context *ctx, const char *name);
NK_API void nk_window_close(struct nk_context *ctx, const char *name);
NK_API void nk_window_collapse(struct nk_context *ctx, const char *name, enum nk_collapse_states state);
NK_API void nk_window_collapse_if(struct nk_context *ctx, const char *name, enum nk_collapse_states, int cond);
NK_API void nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states state);
NK_API void nk_window_show_if(struct nk_context *ctx, const char *name, enum nk_show_states, int cond);

/*
 * ===============================================================
 * 
 *                          LAYOUT
 * 
 * ===============================================================
 */
NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
NK_API void nk_layout_row_dynamic(struct nk_context*, float height, int cols);
NK_API void nk_layout_row_static(struct nk_context*, float height, int item_width, int cols);
NK_API void nk_layout_row_begin(struct nk_context*, enum nk_layout_format, float row_height, int cols);
NK_API void nk_layout_row_push(struct nk_context*, float value);
NK_API void nk_layout_row_end(struct nk_context*);
NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect bounds);
NK_API void nk_layout_space_end(struct nk_context*);
NK_API struct nk_rect nk_layout_space_bounds(struct nk_context*);
NK_API struct nk_rect nk_widget_bounds(struct nk_context*);
NK_API struct nk_rect nk_widget_fitting(struct nk_context*, struct nk_rect, struct nk_vec2);
NK_API struct nk_vec2 nk_widget_position(struct nk_context*);
NK_API struct nk_vec2 nk_widget_size(struct nk_context*);
NK_API float nk_widget_width(struct nk_context*);
NK_API float nk_widget_height(struct nk_context*);
NK_API int nk_widget_is_hovered(struct nk_context*);
NK_API int nk_widget_is_mouse_clicked(struct nk_context*, enum nk_buttons);
NK_API int nk_widget_has_mouse_click_down(struct nk_context*, enum nk_buttons, int down);

/*
 * ===============================================================
 * 
 *                          GROUP
 * 
 * ===============================================================
 */
NK_API int nk_group_begin(struct nk_context*, const char *title, NK_UINT32 flags);
NK_API void nk_group_end(struct nk_context*);

/*
 * ===============================================================
 * 
 *                          TREE
 * 
 * ===============================================================
 */
NK_API int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed);
NK_API int nk_tree_pop(struct nk_context*);
NK_API void nk_tree_state_push(struct nk_context*, enum nk_tree_type, enum nk_collapse_states*);
NK_API void nk_tree_state_pop(struct nk_context*);

#define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, #title, nk_strlen(#title), nk_strlen(#title))

/*
 * ===============================================================
 * 
 *                          WIDGET
 * 
 * ===============================================================
 */
NK_API void nk_text(struct nk_context*, const char*, int, NK_UINT32);
NK_API void nk_text_colored(struct nk_context*, const char*, int, NK_UINT32, struct nk_color);
NK_API void nk_text_wrapped(struct nk_context*, const char*, int, NK_UINT32);
NK_API void nk_text_wrapped_colored(struct nk_context*, const char*, int, NK_UINT32, struct nk_color);
NK_API void nk_label(struct nk_context*, const char*, NK_UINT32 align);
NK_API void nk_label_colored(struct nk_context*, const char*, NK_UINT32 align, struct nk_color);
NK_API void nk_label_wrap(struct nk_context*, const char*);
NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color);
NK_API void nk_image(struct nk_context*, struct nk_image);
NK_API int nk_button_text(struct nk_context*, const char *title, int len);
NK_API int nk_button_label(struct nk_context*, const char *title);
NK_API int nk_button_color(struct nk_context*, struct nk_color);
NK_API int nk_button_symbol(struct nk_context*, enum nk_symbol_type);
NK_API int nk_button_image(struct nk_context*, struct nk_image img);
NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, NK_UINT32 text_alignment);
NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, NK_UINT32 alignment);
NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, NK_UINT32 text_alignment);
NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, NK_UINT32 alignment);
NK_API int nk_button_set_behavior(struct nk_context*, enum nk_button_behavior);
NK_API int nk_check_label(struct nk_context*, const char*, int active);
NK_API int nk_check_text(struct nk_context*, const char*, int, int active);
NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value);
NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value);
NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active);
NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active);
NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value);
NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value);
NK_API int nk_radio_label(struct nk_context*, const char*, int *active);
NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active);
NK_API int nk_option_label(struct nk_context*, const char*, int active);
NK_API int nk_option_text(struct nk_context*, const char*, int, int active);
NK_API int nk_selectable_label(struct nk_context*, const char*, NK_UINT32 align, int *value);
NK_API int nk_selectable_text(struct nk_context*, const char*, int, NK_UINT32 align, int *value);
NK_API int nk_selectable_image_label(struct nk_context*, struct nk_image, const char*, NK_UINT32 align, int *value);
NK_API int nk_selectable_image_text(struct nk_context*, struct nk_image, const char*, int, NK_UINT32 align, int *value);
NK_API int nk_select_label(struct nk_context*, const char*, NK_UINT32 align, int value);
NK_API int nk_select_text(struct nk_context*, const char*, int, NK_UINT32 align, int value);
NK_API int nk_select_image_label(struct nk_context*, struct nk_image, const char*, NK_UINT32 align, int value);
NK_API int nk_select_image_text(struct nk_context*, struct nk_image, const char*, int, NK_UINT32 align, int value);
NK_API float nk_slider_float(struct nk_context*, float min, float val, float max, float step);
NK_API int nk_slider_int(struct nk_context*, int min, int val, int max, int step);
NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int is_modifyable);
NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable);
NK_API void nk_edit_string(struct nk_context*, NK_UINT32 flags, char *buffer, int *len, int max, nk_plugin_filter filter);
NK_API void nk_edit_buffer(struct nk_context*, NK_UINT32 flags, struct nk_text_edit*, nk_plugin_filter filter);
NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel);
NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel);
NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel);
NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel);

/*
 * ===============================================================
 * 
 *                          POPUP
 * 
 * ===============================================================
 */
NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, NK_UINT32 flags, struct nk_rect bounds);
NK_API void nk_popup_close(struct nk_context*);
NK_API void nk_popup_end(struct nk_context*);

/*
 * ===============================================================
 * 
 *                          COMBO
 * 
 * ===============================================================
 */
NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color, struct nk_vec2 size);
NK_API int nk_combo_begin_symbol(struct nk_context*,  enum nk_symbol_type,  struct nk_vec2 size);
NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image, struct nk_vec2 size);
NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
NK_API int nk_combo_begin_image_text(struct nk_context*,  const char *selected, int, struct nk_image, struct nk_vec2 size);
NK_API int nk_combo_item_label(struct nk_context*, const char*, NK_UINT32 alignment);
NK_API int nk_combo_item_text(struct nk_context*, const char*, int, NK_UINT32 alignment);
NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, NK_UINT32 alignment);
NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int, NK_UINT32 alignment);
NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, NK_UINT32 alignment);
NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, NK_UINT32 alignment);
NK_API void nk_combo_close(struct nk_context*);
NK_API void nk_combo_end(struct nk_context*);

/*
 * ===============================================================
 * 
 *                          CHART
 * 
 * ===============================================================
 */
NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int count, float min, float max);
NK_API int nk_chart_begin_colored(struct nk_context*, enum nk_chart_type, struct nk_color, struct nk_color, int count, float min, float max);
NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value);
NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color, int count, float min_value, float max_value);
NK_API NK_UINT32 nk_chart_push(struct nk_context*, float);
NK_API NK_UINT32 nk_chart_push_slot(struct nk_context*, float, int);
NK_API void nk_chart_end(struct nk_context*);
NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset);
NK_API void nk_plot_function(struct nk_context*, enum nk_chart_type, void *userdata, float(*value_getter)(void* user, int index), int count, int offset);

/*
 * ===============================================================
 * 
 *                          MISC
 * 
 * ===============================================================
 */
NK_API struct nk_style_item nk_style_item_image(struct nk_image img);
NK_API struct nk_style_item nk_style_item_color(struct nk_color);
NK_API struct nk_style_item nk_style_item_hide(void);
NK_API void nk_tooltip(struct nk_context*, const char*);
NK_API struct nk_rect nk_tooltip_begin(struct nk_context*, float width);
NK_API void nk_tooltip_end(struct nk_context*);
NK_API void nk_menubar_begin(struct nk_context*);
NK_API void nk_menubar_end(struct nk_context*);
NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, NK_UINT32 align, struct nk_vec2 size);
NK_API int nk_menu_begin_label(struct nk_context*, const char*, NK_UINT32 align, struct nk_vec2 size);
NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size);
NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int, NK_UINT32 align, struct nk_image, struct nk_vec2 size);
NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, NK_UINT32 align, struct nk_image, struct nk_vec2 size);
NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size);
NK_API int nk_menu_begin_symbol_text(struct nk_context*, const char*, int, NK_UINT32 align, enum nk_symbol_type, struct nk_vec2 size);
NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, NK_UINT32 align, enum nk_symbol_type, struct nk_vec2 size);
NK_API int nk_menu_item_label(struct nk_context*, const char*, NK_UINT32 alignment);
NK_API int nk_menu_item_text(struct nk_context*, const char*, int, NK_UINT32 alignment);
NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, NK_UINT32 alignment);
NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int, NK_UINT32 alignment);
NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, NK_UINT32 alignment);
NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, NK_UINT32 alignment);
NK_API void nk_menu_close(struct nk_context*);
NK_API void nk_menu_end(struct nk_context*);
NK_API void nk_contextual_begin(struct nk_context*, NK_UINT32, struct nk_vec2, struct nk_rect trigger_bounds);
NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,NK_UINT32);
NK_API int nk_contextual_item_label(struct nk_context*, const char*, NK_UINT32);
NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, NK_UINT32);
NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int, NK_UINT32);
NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, NK_UINT32);
NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, NK_UINT32);
NK_API void nk_contextual_close(struct nk_context*);
NK_API void nk_contextual_end(struct nk_context*);

/*
 * ===============================================================
 * 
 *                          INPUT
 * 
 * ===============================================================
 */
NK_API void nk_input_begin(struct nk_context*);
NK_API void nk_input_motion(struct nk_context*, int x, int y);
NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
NK_API void nk_input_char(struct nk_context*, char);
NK_API void nk_input_unicode(struct nk_context*, unsigned int);
NK_API void nk_input_end(struct nk_context*);
NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons);
NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect);
NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect);
NK_API int nk_input_is_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
NK_API int nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons);
NK_API int nk_input_is_mouse_released(const struct nk_input*, enum nk_buttons);
NK_API int nk_input_is_key_pressed(const struct nk_input*, enum nk_keys);
NK_API int nk_input_is_key_released(const struct nk_input*, enum nk_keys);
NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys);

/*
 * ===============================================================
 * 
 *                          DRAWING
 * 
 * ===============================================================
 */
NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color);
NK_API void nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect, float rounding, float line_thickness, struct nk_color);
NK_API void nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float x2, float y2, float line_thickness, struct nk_color);
NK_API void nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect, float line_thickness, struct nk_color);
NK_API void nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay, float ctrl1x, float ctrl1y, float ctrl2x, float ctrl2y, float bx, float by, float line_thickness, struct nk_color);
NK_API void nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color);
NK_API void nk_fill_rect(struct nk_command_buffer *b, struct nk_rect, float rounding, struct nk_color);
NK_API void nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
NK_API void nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color);
NK_API void nk_fill_circle(struct nk_command_buffer *b, struct nk_rect, struct nk_color);
NK_API void nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius, float a_min, float a_max, struct nk_color);
NK_API void nk_draw_image(struct nk_command_buffer *b, struct nk_rect, const struct nk_image*, struct nk_color);
NK_API void nk_draw_text(struct nk_command_buffer *b, struct nk_rect, const char *text, int len, const struct nk_user_font*, struct nk_color, struct nk_color);
NK_API void nk_push_scissor(struct nk_command_buffer *b, struct nk_rect);
NK_API void nk_push_custom(struct nk_command_buffer*, struct nk_rect, nk_command_custom_callback, void *usr);

/*
 * ===============================================================
 * 
 *                          HELPER
 * 
 * ===============================================================
 */
NK_API struct nk_rect nk_rect(float x, float y, float w, float h);
NK_API struct nk_rect nk_recti(int x, int y, int w, int h);
NK_API struct nk_vec2 nk_vec2(float x, float y);
NK_API struct nk_vec2 nk_vec2i(int x, int y);
NK_API struct nk_color nk_rgb(int r, int g, int b);
NK_API struct nk_color nk_rgba(int r, int g, int b, int a);
NK_API struct nk_color nk_rgb_f(float r, float g, float b);
NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a);
NK_API struct nk_color nk_hsv(int h, int s, int v);
NK_API struct nk_color nk_hsva(int h, int s, int v, int a);
NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color);
NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color);
NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color);
NK_API void nk_color_hsv_b(char *out_h, char *out_s, char *out_v, struct nk_color);
NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color);
NK_API void nk_color_hsva_i(int *out_h, int *out_s, int *out_v, int *out_a, struct nk_color);
NK_API void nk_color_hsva_b(char *out_h, char *out_s, char *out_v, char *out_a, struct nk_color);
NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color);
NK_API nk_handle nk_handle_ptr(void*);
NK_API nk_handle nk_handle_id(int);
NK_API struct nk_image nk_image_ptr(void*);
NK_API struct nk_image nk_image_id(int);
NK_API int nk_image_is_subimage(const struct nk_image* img);
NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region);
NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region);
NK_API int nk_strlen(const char *str);
NK_API int nk_stricmp(const char *s1, const char *s2);
NK_API int nk_stricmpn(const char *s1, const char *s2, int n);
NK_API int nk_strtoi(const char *str, const char **endptr);
NK_API float nk_strtof(const char *str, const char **endptr);
NK_API int nk_strfilter(const char *text, const char *regexp);
NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score);
NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score);

#ifdef NK_IMPLEMENTATION
/*
 * ===============================================================
 * 
 *                          MATH
 * 
 * ===============================================================
 */
#ifndef NK_SIN
    #define NK_SIN(x) sin(x)
#endif
#ifndef NK_COS
    #define NK_COS(x) cos(x)
#endif
#ifndef NK_SQRT
    #define NK_SQRT(x) sqrt(x)
#endif
#ifndef NK_FLOAT
    #define NK_FLOAT(x) ((float)(x))
#endif

#define NK_PI 3.141592654f
#define NK_MAX(a,b) ((a) > (b) ? (a) : (b))
#define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
#define NK_CLAMP(i,v,x) (NK_MAX(i, NK_MIN(v, x)))

/*
 * ===============================================================
 * 
 *                          UTIL
 * 
 * ===============================================================
 */
#define NK_UTF_INVALID 0xFFFD
#define NK_UTF_SIZE 4

NK_API int nk_utf_decode(const char*, nk_glyph, int);
NK_API int nk_utf_encode(nk_glyph, char*, int);
NK_API int nk_utf_len(const char*, int byte_len);

struct nk_memory_status nk_memory_get_status(struct nk_context*);
void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size capacity);
void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size);
void* nk_buffer_alloc(struct nk_buffer*, enum nk_buffer_type, nk_size size, nk_size align);
void nk_buffer_mark(struct nk_buffer*, enum nk_buffer_type);
void nk_buffer_reset(struct nk_buffer*, enum nk_buffer_type);
void nk_buffer_free(struct nk_buffer*);
void nk_buffer_info(struct nk_memory_status*, struct nk_buffer*);
void* nk_buffer_push(struct nk_buffer*, enum nk_buffer_type, nk_size size, nk_size align);
void* nk_buffer_peek(struct nk_buffer*, enum nk_buffer_type, nk_size size, nk_size align);
void nk_buffer_pop(struct nk_buffer*, enum nk_buffer_type, nk_size size);
void nk_buffer_clear(struct nk_buffer*);

void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size);
void nk_str_init_fixed(struct nk_str*, void *memory, nk_size size);
void nk_str_clear(struct nk_str*);
void nk_str_free(struct nk_str*);
int nk_str_append_text_char(struct nk_str*, const char*, int);
int nk_str_append_str_char(struct nk_str*, const char*);
int nk_str_append_text_utf8(struct nk_str*, const char*, int);
int nk_str_append_str_utf8(struct nk_str*, const char*);
int nk_str_insert_text_char(struct nk_str*, int, const char*, int);
int nk_str_insert_str_char(struct nk_str*, int, const char*);
int nk_str_insert_text_utf8(struct nk_str*, int, const char*, int);
int nk_str_insert_str_utf8(struct nk_str*, int, const char*);
void nk_str_remove_text(struct nk_str*, int, int);
void nk_str_remove_str(struct nk_str*, int, int);
void nk_str_delete_text(struct nk_str*, int, int);
void nk_str_delete_str(struct nk_str*, int, int);
char* nk_str_at_char(struct nk_str*, int);
char* nk_str_at_text(struct nk_str*, int, int*, int*);
const char* nk_str_at_char_const(const struct nk_str*, int);
const char* nk_str_at_text_const(const struct nk_str*, int, int*, int*);

void nk_text_edit_init(struct nk_text_edit*, struct nk_allocator*, nk_size size);
void nk_text_edit_init_fixed(struct nk_text_edit*, void *memory, nk_size size);
void nk_text_edit_free(struct nk_text_edit*);
void nk_text_edit_text(struct nk_text_edit*, const char*, int total_len);
void nk_text_edit_delete(struct nk_text_edit*, int where, int len);
void nk_text_edit_delete_selection(struct nk_text_edit*);
void nk_text_edit_select_all(struct nk_text_edit*);
int nk_text_edit_paste(struct nk_text_edit*, const char*, int len);
void nk_text_edit_undo(struct nk_text_edit*);
void nk_text_edit_redo(struct nk_text_edit*);

#endif /* NK_IMPLEMENTATION */

#ifdef __cplusplus
}
#endif

#endif /* NK_H_ */
